package router

import (
	"api/middleware"
	model2 "api/model"
	errormsg "api/utils/error"
	"broker/interface/iserver"
	"broker/struct/datapack"
	"broker/struct/model"
	"broker/utils"
	"broker/utils/logger"
	"errors"
	"strings"
)

type ConnectRouter struct {
	BaseRouter
}

func NewConnectRouter() *ConnectRouter {
	return &ConnectRouter{}
}

func (cr ConnectRouter) disConnect(request iserver.IRequest, err error) {
	logger.Error.Println(err)
	request.GetConnection().Stop()
}

func (cr *ConnectRouter) PreHandle(request iserver.IRequest) interface{} {

	///解包连接数据
	msgData := request.GetData()
	cdp := datapack.NewConnectDataPack()
	connMsg, err := cdp.UnPack(msgData)
	if err != nil {
		cr.disConnect(request, err)
	}
	//保存连接信息
	request.GetConnection().SetProperty("ConnectMsg", connMsg)
	return connMsg
}

func (cr *ConnectRouter) Handle(request iserver.IRequest, param interface{}) interface{} {

	connMsgData := param.(*model.ConnectMessage)

	connAckMsg := model.NewConnectACKMessage()
	connAckMsg.ConnACKFlag = 0x00

	if strings.Contains(connMsgData.UserName, "&") {
		deviceName := strings.Split(connMsgData.UserName, "&")[0]
		deviceKey := strings.Split(connMsgData.UserName, "&")[1]

		device := model2.NewDeviceModel()
		device.Name = deviceName
		device.Key = deviceKey
		dbdevice := device.SelectDeviceByNameKey()
		if dbdevice.ID == 0 {
			connAckMsg.ConnReturnCode = model.AuthErr
		} else {
			dsm := model2.NewDeviceSecretModel()
			dsm.DID = dbdevice.ID
			dbdsm := dsm.Select()

			if utils.HmacSha(dbdsm.Secret, connMsgData.UserName) == connMsgData.PassWord {
				request.GetConnection().SetProperty("deviceName", deviceName)
				request.GetConnection().SetProperty("deviceKey", deviceKey)
				request.GetConnection().SetProperty("deviceID", dbdevice.ID)
				request.GetConnection().SetProperty("userId", dbdevice.UID)

				request.GetConnection().GetTcpServer().CallOnConnStart(request.GetConnection())
				connAckMsg.ConnReturnCode = model.ConnectACK
			} else {
				connAckMsg.ConnReturnCode = model.AuthErr
			}
		}

	} else {
		claim, err := middleware.CheckToken(connMsgData.PassWord)
		if err != errormsg.SUCCSE {
			connAckMsg.ConnReturnCode = model.AuthErr
		} else {
			user := model2.NewUserModel()
			user.ID = claim.UID
			dbuser := user.Select()
			if dbuser.ID > 0 {
				connAckMsg.ConnReturnCode = model.ConnectACK
			} else {
				connAckMsg.ConnReturnCode = model.AuthErr
			}
		}
	}
	return connAckMsg
}

func (cr *ConnectRouter) PostHandle(request iserver.IRequest, param interface{}) {
	connAckMsg := param.(*model.ConnectACKMessage)
	//封装ConnAck
	connAckDP := datapack.NewConnectACKDataPack()
	connAckData, err := connAckDP.Pack(connAckMsg)
	if err != nil {
		cr.disConnect(request, errors.New("封装连接响应数据错误"))
	}
	connAckMsg.SetData(connAckData)
	go request.GetConnection().SendMsg(connAckMsg)
}
